#library('BubbleGrid');
#import('dart:html');
#import('Colors.dart');
#import('Bubble.dart');

/** Keeps track of the grid of bubbles as well as the user's total points. */
class BubbleGrid {
  
  // The dimensions of the grid
  int height;
  int length;
  
  // A list representing the table of bubbles
  List<Bubble> bubbles;
  
  // Keeping track of the total number of points
  int totalPoints;
  
  // Constructor
  BubbleGrid(int height, int length) {
    this.height = height;
    this.length = length;
    this.totalPoints = 0;
  }
  
  // Returns the size of the grid
  int size() { 
    return height * length;
  }

  // Initialize the list of bubbles with random colors
  void initializeBubbles() {
    bubbles = new List(size());
    for (int i=0; i < size(); i++) {
      bubbles[i] = new Bubble(Colors.getColors()[(Math.random() * 5).floor().toInt()]);
    }
  }
  

  // Remove the given bubbles corresponding to the given list of indices from the grid.
  void removeGroup(List<int> selected) {
  
    // Replace each of the selected bubbles with an empty image.
    for (int index in selected) {
      bubbles[index].color = null;
    }
  
    // Slide down bubbles above the empty spaces
    for (int i=0; i<length; i++) {
      for (int j=height-1; j>=0; j--) {
        int index = j * length + i;
        if (bubbles[index].color == null) {
          int temp = index;
          while(temp > -1 && bubbles[temp].color == null) {
            temp = temp - length;
          }
          if (temp > - 1) {
            bubbles[index].color = bubbles[temp].color;
            bubbles[temp].color = null;
          }
        }
      }
    }
  }

  // Remove empty columns by sliding bubbles to the right.
  void removeEmptyColumns() {

    //for each column, check if it is empty
    for (int i=1; i<length; i++) {
      bool isEmpty = true;
      for (int k=0; k<height; k++) {
        isEmpty = isEmpty && (bubbles[k * length + i].color == null);
      }

      // If it is empty, slide all bubbles to the left of it over by one column.
      if (isEmpty) {
        for (int j=i; j>0; j--) {
          for (int k=0; k<height; k++) {
            bubbles[k * length + j].color = bubbles[k * length + j - 1].color;
            }
          }
        for (int k=0; k<height; k++) {
          bubbles[k * length].color = null;
        }
      }
    }
  }

  // Returns whether there is no possible move on the grid.
  // If so, the game is over.
  bool isGameOver() {
  
    // Check if there is any bubble with a neighbour of the same color
    for (int bubble =0; bubble<bubbles.length; bubble++) {
      var color = bubbles[bubble].color;
      var right = bubble + 1;
      var left = bubble - 1;
      var down = bubble + length;
      var up = bubble - length;
      if (color != null && ( 
          ( right % length != 0 && color == bubbles[right].color ) ||
          ( bubble % length != 0 && color == bubbles[left].color ) || 
          ( up > -1 && color == bubbles[up].color ) || 
          ( down < size() && color == bubbles[down].color ) )) {
        return false;
       }
    }
    
    return true;
  }
}
